package de.tudarmstadt.ukp.muip.fibqdojo.util;

import java.util.LinkedList;
import java.util.List;

import de.tudarmstadt.ukp.muip.fibqdojo.interfaces.IFIBQToken;
import de.tudarmstadt.ukp.muip.fibqdojo.visitor.GetFormVisitor;

public class NGram {

    private final int ngram;
    private List<IFIBQToken> gramData;
    private String separator;

    public NGram(int size, String separator) {
        validateSize(size);
        this.ngram = size;
        this.gramData = new LinkedList<IFIBQToken>();
        this.separator = separator;
    }

    public NGram(int size, String separator, List<IFIBQToken> tokens) {
        validateSize(size);
        this.ngram = size;
        validateNumberOfTokensForNgram(tokens);
        this.gramData = tokens;
        this.separator = separator;
    }

    private void validateSize(int size) {
        if (size <= 0) {
            throw new IllegalArgumentException("Size must be >= 1");
        }
    }
    
    public int getNGramSize() {
        return ngram;
    }

    public void setNGram(List<IFIBQToken> tokens) {
        validateNumberOfTokensForNgram(tokens);
        gramData.clear();
        gramData.addAll(tokens);
    }

    private void validateNumberOfTokensForNgram(List<IFIBQToken> list) {
        if (list.size() != ngram) {
            throw new IllegalArgumentException("This instance only takes " + ngram + " grams");
        }
    }

    public String getConcatNGram() {
        String concat = "";
        for (IFIBQToken token : gramData) {
            GetFormVisitor visitor = new GetFormVisitor();
            token.accept(visitor);
            concat += visitor.getForm() + separator;
        }
        return concat.trim();
    }

    public String getConcatNGram(int start, int end) {
        String string = "";

        if (start < 0 || end >= gramData.size() || end < start) {
            return "";
        }

        for (int i = start; i <= end; i++) {
            GetFormVisitor visitor = new GetFormVisitor();
            gramData.get(i).accept(visitor);
            string += visitor.getForm() + separator;
        }

        return string.trim();
    }

    @Override
    public String toString() {
        return getConcatNGram();
    }

    public void setSeparator(String separator) {
        this.separator = separator;
    }

    public IFIBQToken getTokenAt(int index) {
        return gramData.get(index);
    }

}
